<!--报表管理 - ppm报表-->
<template>
  <basic-container>
    <el-tabs type="border-card" class="tab-font">
      <el-tab-pane label="搜索">
        <avue-form ref="form" :option="option" v-model="form">
          <!-- <template slot="week">
            <el-date-picker
              v-model="date"
              @change="changeDate()"
              type="daterange"
              align="center"
              unlink-panels
              range-separator="-"
              start-placeholder="开始周"
              end-placeholder="结束周"
              show-week-number="true"
              size="small"
              class="date-class"
              :format="format"
              :picker-options="pickerOptions"
              value-format="yyyy 第 WW 周"
              prefix-icon="calendar-icon"
            >
            </el-date-picker>
          </template> -->
          <template slot="weekStart">
            <el-date-picker v-model="form.weekStart" :picker-options="pickerOptions" type="week" format="yyyy 第 WW 周" placeholder="起始周"> </el-date-picker>
          </template>
          <template slot="weekEnd">
            <el-date-picker v-model="form.weekEnd" :picker-options="pickerOptions" type="week" format="yyyy 第 WW 周" placeholder="结束周"> </el-date-picker>
          </template>
          <template slot="weekEnd"></template>
          <template slot="containLabel"><span style="color: #f56c6c; margin-right: 4px">*</span>{{ productionMap[activeName] }}: </template>
          <template slot="contain">
            <el-input :class="{ 'invalid-input': isValid }" placeholder="请选择产品" readonly="true" disabled v-model="form.product" v-if="activeName === 'product'">
              <el-button slot="append" icon="el-icon-search" @click="openPartNoCommonModal('partNoModal')"></el-button>
            </el-input>
            <el-input :class="{ 'invalid-input': isValid }" placeholder="请选择工序" readonly="true" disabled v-model="form.process" v-if="activeName === 'process'">
              <el-button slot="append" icon="el-icon-search" @click="openStationModel"></el-button>
            </el-input>
            <el-input :class="{ 'invalid-input': isValid }" placeholder="请选择设备" readonly="true" v-model="form.device" disabled v-if="activeName === 'device'">
              <el-button slot="append" icon="el-icon-search" @click="openEquipmentModel"></el-button>
            </el-input>
            <el-input :class="{ 'invalid-input': isValid }" placeholder="请输入人员" v-model="form.personnel" v-if="activeName === 'personnel'"> </el-input>
            <el-select
              :class="{ 'invalid-input': isValid }"
              placeholder="请选择车间"
              v-model="form.workshopId"
              multiple-limit="5"
              filterable
              multiple
              v-if="activeName === 'workshop'"
              @change="isValid = false"
            >
              <el-option v-for="item in optionList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
            </el-select>
            <el-select :class="{ 'invalid-input': isValid }" placeholder="请选择班组" v-model="form.team" multiple-limit="5" filterable multiple v-if="activeName === 'team'">
              <el-option v-for="item in optionList" :key="item.value" :label="item.label" :value="item.value"> </el-option>
            </el-select>
            <span class="invalid-span" v-if="isValid">{{ validateMsg }}</span>
          </template>
          <template slot="btn">
            <el-button type="primary" size="small" class="el-icon-search" @click="handleSubmit">搜索</el-button>
            <el-button size="small" class="el-icon-delete" @click="handleCancel">清空</el-button>
          </template>
        </avue-form>
      </el-tab-pane>
    </el-tabs>
    <div class="page-contianer">
      <el-tabs type="border-card" class="chart-tab tab-font" v-model="activeName" @tab-click="handleClick">
        <el-tab-pane label="车间" name="workshop"></el-tab-pane>
        <el-tab-pane label="产品" name="product"></el-tab-pane>
        <el-tab-pane label="设备" name="device"></el-tab-pane>
        <el-tab-pane label="工序" name="process"></el-tab-pane>
        <el-tab-pane label="班组" name="team"></el-tab-pane>
        <!-- <el-tab-pane label="人员" name="personnel"></el-tab-pane> -->
        <div class="main-content">
          <el-row :gutter="20">
            <el-col :span="24">
              <chart-view class="chart-content" :chart-option="chartOption" :auto-resize="true" width="100%" />
              <avue-crud :option="tableOption" :table-loading="loading" :data="data" :page.sync="tablePage" @current-change="currentChange" @size-change="sizeChange" ref="crud">
                <template slot="menuLeft">
                  <el-button type="warning" size="small" icon="el-icon-download" @click="handleExport">导出 </el-button>
                </template>
                <template slot="menuRight" v-if="searchTime">
                  <div class="search-time">
                    <span> 当前查询时间:{{ searchTime }} </span>
                  </div>
                </template>
              </avue-crud>
            </el-col>
          </el-row>
        </div>
      </el-tabs>

      <export-comp
        ref="exportComp"
        page-api-url="mes-abacus/stat-production-query/page-query-production-yield-report"
        :option="tableOption"
        :page="tablePage"
        :query="exprotParams"
        file-name="生产产量查询"
      >
      </export-comp>
      <el-dialog title="查询进度" :visible.sync="dialogVisible" width="30%" append-to-body>
        <el-progress :percentage="currentProgress" stroke-width="40" stroke-linecap="square" :show-text="false"> </el-progress>
      </el-dialog>
    </div>
    <common-modal-template ref="commonModalTemplate" :option="selectOption" @getSelectedRows="getSelectedRows" :key="timer" @newKey="newKey"> </common-modal-template>
  </basic-container>
</template>

<script>
import ChartView from '@/components/chart/index.vue';
import moment from 'moment';
import { getParamDetail } from '@/api/system/param';
import { getTableList, getWorkshop, getChartData } from '@/api/report/production-query';
import { tableOption, getOption, getStatisticType, getStartDay, getEndDay, getTableOption, valiDateFlied } from '@/views/report/production-query.js';
import exportComp from '@/components/export-comp';
import commonModalTemplate from '@/components/common-modal-template/common-modal-template';
export default {
  name: 'production-query',
  components: {
    ChartView,
    exportComp,
    commonModalTemplate
  },
  data() {
    return {
      isValid: false,
      exprotParams: {},
      selectOption: {},
      modalName: '',
      timer: new Date().getTime(),
      currentProgress: 0,
      intervalId: null,
      dialogVisible: false,
      activeName: 'workshop',
      pickerOptions: {
        firstDayOfWeek: 1
      },
      search: {
        workshopName: '',
        workshopList: []
      },
      optionList: [],
      searchTime: '',
      productionMap: {
        workshop: '车间',
        product: '产品',
        device: '设备',
        process: '工序',
        team: '班组',
        personnel: '人员'
      },
      params: {
        startDate: '',
        endDate: '',
        workshopName: '',
        statisticsTimeDimension: 'DAY'
      },
      form: {
        examineDate: this.getDefaultTime(),
        week: []
      },
      loading: false,
      data: [],
      tableOption,
      tablePage: {
        pageSize: 20,
        currentPage: 1,
        total: 0
      },
      option: getOption(this),
      chartOption: {
        tooltip: {
          trigger: 'axis'
          // formatter: '{a0}: {c0}<br />{a1}: {c1}%'
        },
        legend: {
          top: '10%',
          tooltip: {
            show: true
          }
        },
        xAxis: {
          type: 'category',
          boundaryGap: false,
          data: [],
          name: '日期'
        },
        yAxis: {
          type: 'value'
        },
        series: []
      }
    };
  },
  computed: {
    validateMsg() {
      return '请选择' + this.productionMap[this.activeName];
    }
  },
  mounted() {
    this.initCalendarStartDay();
    this.getOptionList('workshop');
  },
  methods: {
    initCalendarStartDay() {
      getParamDetail({ paramKey: 'calendar_start_sunday' })
        .then((res) => {
          if (res.data.code === 200) {
            this.pickerOptions.firstDayOfWeek = Number(res.data.data.paramValue);
          }
        })
        .catch((err) => {});
    },
    newKey() {
      this.timer = new Date().getTime();
    },

    getOptionList(filed) {
      const filedMap = {
        workshop: { dimension: 'WORK_SHOP' },
        team: { dimension: 'SHIFT_GROUP' }
      };
      getWorkshop(filedMap[filed])
        .then((res) => {
          let data = res.data.data;
          this.optionList = data.map((d) => {
            return {
              label: d.name,
              value: d.id
            };
          });
        })
        .catch((err) => {});
    },
    async onLoad() {
      const startTime = new Date().getTime();
      let endTime;
      let data;
      // doajax
      const params = this.getParams();
      const pageParams = {
        current: this.tablePage.currentPage,
        size: this.tablePage.pageSize
      };
      try {
        const res = await getTableList(Object.assign(params, pageParams));
        data = (res.data.data || {}).records;
        this.tablePage.total = res.data.data.total;
        this.endTime = new Date().getTime();
      } catch (e) {
        endTime = new Date().getTime();
        this.setChartOption([]);
        data = [];
      }
      const seconds = endTime - startTime;
      this.startProgress(data, seconds);
    },
    sizeChange(pageSize) {
      this.tablePage.pageSize = pageSize;
      this.onLoad();
    },
    currentChange(currentPage) {
      this.tablePage.currentPage = currentPage;
      this.onLoad();
    },
    handleSubmit() {
      this.currentProgress = 0;
      const valid = valiDateFlied(this.form, this.activeName);
      if (!valid) {
        // this.$message.error(`请选择${this.productionMap[this.activeName]}`);
        this.isValid = true;
        return;
      }
      this.$refs.form.validate((valid, done) => {
        if (valid) {
          this.dialogVisible = true;
          this.onLoad();
          this.getChartData();
          done();
        }
      });
    },
    getParams() {
      let params = {};
      let weekParams = {};
      const timeDimension = this.form.statisticsTimeDimension;
      const queryParams = this.getQueryParams(this.activeName);
      const timeArr = this.getTime(timeDimension);
      const baseParams = {
        statisticType: getStatisticType(this.activeName), //统计类型
        timeDimension, //时间维度
        startDate: getStartDay(timeArr[0], timeDimension),
        endDate: getEndDay(timeArr[1], timeDimension)
      };
      if (timeDimension === 'WEEK') {
        weekParams = {
          //  weekEndDate: 'Sunday', //getStartDay(this.form.weekStart, 'week'),
          weekStartDate: 'Monday'
        };
      }
      if (timeDimension === 'WEEK') {
        params = {
          ...baseParams,
          ...queryParams,
          ...weekParams
        };
      } else {
        params = {
          ...baseParams,
          ...queryParams
        };
      }
      return params;
    },
    getTime(type) {
      if (type === 'DAY') {
        return this.form.examineDate;
      } else if (type === 'WEEK') {
        return [this.form.weekStart, this.form.weekEnd];
      } else {
        return this.form.month;
      }
    },
    getQueryParams(type) {
      let obj = {};
      switch (type) {
        case 'workshop':
          obj.workshopId = this.form.workshopId.toString();
          break;
        case 'product':
          obj.partMasterId = this.form.partMasterId;
          break;
        case 'device':
          obj.equipmentId = this.form.equipmentId;
          break;
        case 'process':
          obj.routeName = this.form.routeName;
          break;
        case 'team':
          break;
      }
      return obj;
    },

    async getChartData() {
      let data = [];
      try {
        const params = this.getParams();
        const res = await getChartData(params);
        data = res.data.data;
      } catch (e) {
        data = [];
        this.data = [];
      }
      this.setChartOption(data);
    },
    startProgress(data, seconds = 500) {
      const time = seconds < 500 ? 500 : seconds;
      const setInterTime = time / 10;
      this.intervalId = setInterval(() => {
        if (this.currentProgress < 100) {
          this.currentProgress += 10;
        } else {
          clearInterval(this.intervalId);
          this.dialogVisible = false;
          this.data = data;
        }
      }, setInterTime);
    },
    setChartOption(data = []) {
      let xAxisData = data.length > 0 ? data[0].date : [];
      let series = [];
      data.forEach((item) => {
        series.push({
          name: item.name,
          type: 'line',
          data: item.yield.map((i) => Number(i))
        });
      });
      const xAxis = {
        type: 'category',
        boundaryGap: false,
        data: xAxisData
      };
      this.$set(this.chartOption, 'xAxis', xAxis);
      this.$set(this.chartOption, 'series', series);
    },
    getDefaultTime() {
      let defaultStartTime = this.$moment(new Date()).subtract(6, 'days').format('yyyy-MM-DD');
      let defaultEndTime = this.$moment(new Date()).subtract(0, 'days').format('yyyy-MM-DD');
      return [defaultStartTime, defaultEndTime];
    },
    handleClick() {
      if (['team', 'workshop'].includes(this.activeName)) {
        this.getOptionList(this.activeName);
      }
      const colum = getTableOption(this.activeName);
      this.$set(this.tableOption, 'column', colum);
      this.$refs.crud.refreshTable();
      this.$refs.form.resetForm();
      this.$nextTick(() => {
        this.form = {
          statisticsTimeDimension: 'DAY',
          examineDate: this.getDefaultTime()
        };
      });
      this.data = [];
      this.setChartOption([]);
    },
    handleCancel() {
      this.isValid = false;
      this.data = [];
      this.setChartOption([]);
      this.$refs.form.resetForm();
      this.$nextTick(() => {
        this.form = {
          statisticsTimeDimension: 'DAY',
          examineDate: this.getDefaultTime()
        };
      });
    },
    getSelectedRows(rowData) {
      if (rowData.length) {
        this.isValid = false;
      }
      if (rowData.length > 5) {
        this.$message.warning(`最多选择5个${this.productionMap[this.activeName]}`);
        return;
      }
      if (this.modalName === 'stationModel') {
        const routeName = rowData.map((i) => i.name).toString();
        this.form.routeName = routeName;
        this.form.process = routeName;
      } else if (this.modalName === 'partNoModal') {
        this.form.partMasterId = rowData.map((i) => i.id).toString();
        this.form.product = rowData.map((i) => i.name).toString();
      } else if (this.modalName === 'equipmentModel') {
        this.form.equipmentId = rowData.map((i) => i.id).toString();
        this.form.device = rowData.map((i) => i.name).toString();
      }
    },
    handleExport() {
      const valid = valiDateFlied(this.form, this.activeName);
      if (!valid) {
        this.isValid = true;
        // this.$message.error(`请选择${this.productionMap[this.activeName]}`);
        return;
      }
      this.$refs.form.validate((valid, done) => {
        if (valid) {
          this.exprotParams = this.getParams();
          this.$refs.exportComp.visible = true;
        }
      });
    },
    openPartNoCommonModal() {
      this.modalName = 'partNoModal';
      this.$refs.commonModalTemplate.showModal();
      this.selectOption = {
        modalTitle: '选择产品信息',
        url: '/api/mes-admin/part-master/page?semifinished=true',
        isPage: true,
        columnDefs: [
          {
            label: '类型',
            prop: 'categoryId',
            search: true,
            type: 'tree',
            dicUrl: '/api/mes-admin/part-category/tree',
            props: {
              label: 'title',
              value: 'id'
            }
          },
          {
            label: '编码',
            prop: 'partNo',
            search: true
          },
          {
            label: '名称',
            prop: 'name',
            search: true
          },
          {
            label: '型号',
            prop: 'partModel'
          },
          {
            label: '描述',
            prop: 'description'
          },
          {
            label: '版本',
            prop: 'revision'
          }
        ]
      };
    },
    openStationModel() {
      this.modalName = 'stationModel';
      this.$refs.commonModalTemplate.showModal();
      this.selectOption = {
        modalTitle: '选择工序信息',
        url: '/api/mes-product/apaas/workstation/page',
        isPage: true,
        columnDefs: [
          {
            label: '名称',
            prop: 'name',
            search: true
          },
          {
            label: '工站类型',
            prop: 'type',
            type: 'select',
            search: true,
            dicData: [
              //可做返回类型的转换
              {
                label: '过站',
                value: 'OVERSTATION'
              },
              {
                label: '报工',
                value: 'TIMESHEET'
              },
              {
                label: '测试',
                value: 'TEST'
              },
              {
                label: '老化',
                value: 'AGING'
              },
              {
                label: '包装',
                value: 'PACKING'
              },
              {
                label: '组装',
                value: 'ASSEMBLY'
              },
              {
                label: '上料',
                value: 'FEEDING'
              }
            ]
          },
          {
            label: '编码',
            prop: 'code',
            width: 250
          }
        ]
      };
    },
    openEquipmentModel() {
      this.modalName = 'equipmentModel';
      this.$refs.commonModalTemplate.showModal();
      this.selectOption = {
        modalTitle: '选择设备信息',
        url: '/api/mes-product/ems-equipment/page?type=PRINTER',
        isPage: true,
        columnDefs: [
          {
            label: '编码',
            prop: 'code',
            rules: [
              {
                required: true,
                message: '请输入编码',
                trigger: 'blur'
              }
            ]
          },
          {
            label: '名称',
            prop: 'name',
            search: true,
            rules: [
              {
                required: true,
                message: '请输入名称',
                trigger: 'blur'
              }
            ]
          },
          {
            label: '类型',
            prop: 'categoryName',
            type: 'search',
            placeholder: '请选择 类型',
            rules: [
              {
                required: true,
                message: '请选择类型',
                trigger: 'blur'
              }
            ]
          }
        ]
      };
    },
    validateDateRange(rule, value, callback) {
      if (!this.form.month.length) {
        callback(new Error('请选择时间范围'));
      }
      // 假设有两个时间对象：startTime 和 endTime
      const startTime = moment(this.form.month[0], 'YYYY-MM');
      const endTime = moment(this.form.month[1], 'YYYY-MM');

      // 计算两个时间之间的月份差
      const monthDiff = endTime.diff(startTime, 'months');

      if (monthDiff <= 12) {
        callback();
      } else {
        // 月份差大于 12，超出范围
        callback(new Error('月范围不能超过 12 个月'));
      }
    },
    validateWeek(rule, value, callback) {
      const startTime = moment(this.form.weekStart, 'yyyy-MM-DD');
      const endTime = moment(this.form.weekEnd, 'yyyy-MM-DD');
      const monthDiff = endTime.diff(startTime, 'days');
      if (monthDiff >= 96) {
        callback(new Error('时间范围不能超过12周'));
      } else if (monthDiff < 0) {
        callback(new Error('结束周不能早于开始周'));
      } else {
        callback();
      }
    }
  }
};
</script>

<style scoped lang="scss">
.page-contianer {
  margin-top: 20px;
  height: calc(100vh - 160px);
}
.main-content {
  height: 650px;
  overflow-y: scroll;
  overflow-x: hidden;
}
.chart-header {
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 10px;
  height: 40px;

  .workshopSelect {
    position: absolute;
    left: 100px;
  }

  .opration-div {
    position: absolute;
    left: 50px;
    font-size: 14px;
    color: #606266;
  }
}
.search-time {
  font-size: 14px;
  color: #606266;
  height: 40px;
  display: flex;
  flex-direction: column;
  flex-wrap: nowrap;
  justify-content: flex-end;
  span {
    display: inline-block;
  }
}
.tab-font {
  ::v-deep .el-tabs__item {
    color: #606266 !important;
    font-weight: bold;
  }
}
.invalid-input {
  position: relative;
  ::v-deep .el-input__inner {
    border: 1px solid #f56c6c;
  }
}
.invalid-span {
  color: #f56c6c;
  font-size: 12px;
  line-height: 1;
  padding-top: 4px;
  position: relative;
  top: -7px;
}
</style>
